<script setup lang="ts">
import type { GDVSceneConfig, Scene } from './index';

import { computed, onBeforeMount, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';

import { Page } from '@vben/common-ui';
import {
  ElArrowDown,
  ElCalendar,
  ElClock,
  ElDataAnalysis,
  ElDelete,
  ElEdit,
  ElGrid,
  ElList,
  ElPlus,
  ElRefresh,
  ElSearch,
  ElShare,
  ElSort,
  ElStar,
  ElUploadFilled,
} from '@vben/icons';

import { StorageManager } from '@vben-core/shared/cache';

import {
  ElAvatar,
  ElButton,
  ElCard,
  ElCol,
  ElConfigProvider,
  ElDropdown,
  ElDropdownItem,
  ElDropdownMenu,
  ElEmpty,
  ElIcon,
  ElInput,
  ElMessage,
  ElPagination,
  ElPopconfirm,
  ElTooltip,
} from 'element-plus';

import { sceneApi, userApi } from '#/api';
import { ADMIN_EMAIL } from '#/constant';
import { $t } from '#/locales';
import { useSceneStore } from '#/store';

// 初始化 storage
const storageManager = new StorageManager({
  prefix: '',
  storageType: 'sessionStorage',
});

const router = useRouter();
const sceneStore = useSceneStore();

const userName = storageManager.getItem<string>('username');

const userId = storageManager.getItem<string>('userId') as string;

const isAdmin = ref(false);
const currentPage = ref(1);
const pageSize = ref(8);
const totalDataCount = ref(0);
const isLoading = ref(true);
const keyword = ref('');
const isSceneEmpty = ref(false);
const isSearchEmpty = ref(false);

const sceneList = reactive({ data: [] as Scene[] });
const currentSceneList = reactive({ data: [] as Scene[] });

const adminInfo = ref({
  avatar: '',
  email: '',
  institution: '',
  userName: '',
});

const sceneTypeInfo = reactive({
  id: 1,
  label: $t('scenes.types.gdv'),
  value: 'GDV',
});

// 仅一个场景类型，直接返回
const displaySceneType = () => {
  return sceneTypeInfo.label;
};

const getTypeColor = () => {
  return 'bg-blue-600';
};

const isAdminFn = () => {
  if (storageManager.getItem('email') === ADMIN_EMAIL) {
    isAdmin.value = true;
  }
};

const getAdminInfo = async () => {
  adminInfo.value = await userApi.getUserInfoByEmail(ADMIN_EMAIL);
};

const sceneDisplayTypes = [
  {
    label: $t('scenes.displayType.grid'),
    value: 'grid',
  },
  {
    label: $t('scenes.displayType.list'),
    value: 'list',
  },
];

const sortByFields = [
  {
    label: $t('scenes.sortBy.updateTime'),
    value: 'updateTime',
  },
  {
    label: $t('scenes.sortBy.createTime'),
    value: 'createTime',
  },
  {
    label: $t('scenes.sortBy.name'),
    value: 'name',
  },
];

const activeSceneDisplayType = ref(sceneDisplayTypes[1]);
const isGridMode = computed(
  () => activeSceneDisplayType?.value?.value === 'grid',
);

const toggleDisplayType = () => {
  activeSceneDisplayType.value!.value = isGridMode.value ? 'list' : 'grid';
};

const activeSortedField = ref(sortByFields[0]);

const handleSortCommand = (command: string) => {
  activeSortedField.value =
    sortByFields.find((field) => field.value === command) || sortByFields[0];

  const sorted = [...sceneList.data];
  switch (activeSortedField?.value?.value) {
    case 'createTime': {
      sorted.sort(
        (a, b) =>
          new Date(b.createdTime).getTime() - new Date(a.createdTime).getTime(),
      );
      break;
    }
    case 'name': {
      sorted.sort((a, b) => a.sceneName.localeCompare(b.sceneName));
      break;
    }
    case 'updateTime': {
      sorted.sort(
        (a, b) =>
          new Date(b.lastUpdatedTime).getTime() -
          new Date(a.lastUpdatedTime).getTime(),
      );
      break;
    }
  }
  currentSceneList.data = sorted;
  return sorted;
};

const handleEmptySceneList = (res: any) => {
  if (res.body.length === 0) {
    isSceneEmpty.value = true;
    isSearchEmpty.value = false;
    ElMessage.warning('暂未创建场景');
  } else {
    ElMessage.warning('暂无相关场景');
    isSceneEmpty.value = false;
    isSearchEmpty.value = true;
  }
  setTimeout(() => {
    isLoading.value = false;
  }, 500);
};

const processSceneListResponse = (res: any) => {
  sceneList.data = res.body.map((item: any) => ({
    sceneId: item.id,
    sceneName: item.name,
    sceneType: 'GDV',
    sceneImg: item.thumbnail
      ? `${item.thumbnail}?version=${Date.now()}`
      : item.thumbnail,
    userId: item.createdUser,
    editCount: item.editCount,
    createdTime: item.createdTime,
    lastUpdatedTime: item.updatedTime,
    isLocked: item.isLocked,
    permissionRange: item.permissionRange,
  }));
  currentSceneList.data = sceneList.data;
  totalDataCount.value = res.count;

  if (sceneList.data.length === 0) {
    if (keyword.value) {
      sceneApi
        .getSceneList(userId, pageSize.value, currentPage.value, '')
        .then(handleEmptySceneList);
    } else {
      handleEmptySceneList(res);
    }
  } else {
    isSceneEmpty.value = false;
    isSearchEmpty.value = false;
    setTimeout(() => {
      isLoading.value = false;
    }, 500);
  }
};

const flushSceneList = () => {
  isLoading.value = true;
  sceneApi
    .getSceneList(userId, pageSize.value, currentPage.value, keyword.value)
    .then(processSceneListResponse);
};

const enterGDVScene = (type: string, scene?: Scene) => {
  const newScene: Scene = {
    sceneId: '',
    sceneName: 'untitled',
    sceneType: 'GDV',
    sceneImg: '',
    userId,
    editCount: 0,
    createdTime: '',
    lastUpdatedTime: '',
    isLocked: false,
    permissionRange: 16,
  };
  if (type === 'beforeCreate') {
    storageManager.setItem('editingScene', newScene);
    router.push('/gdv-scene-editor/untitled');
  } else {
    storageManager.setItem('editingScene', scene);
    router.push(`/gdv-scene-editor/${scene?.sceneId}`);
  }
};

const enterScene = (type: string, scene?: Scene) => {
  sceneStore.setEditingScene({} as Scene);
  sceneStore.setCurrentSceneConfig({} as GDVSceneConfig);
  enterGDVScene(type, scene);
};

const handleCreateSceneConfirm = () => {
  enterScene('beforeCreate');
};

const deleteScene = (sceneId: string) => {
  sceneApi
    .deleteScene(userId, sceneId)
    .then(() => {
      flushSceneList();
      ElMessage.success($t('scenes.errorMessages.deleteSceneSuccess'));
    })
    .catch(() => {
      ElMessage.error($t('scenes.errorMessages.deleteSceneFailed'));
    });
};

const publishScene = (sceneId: string) => {
  sceneApi.publishScene(userId, sceneId).then(() => {
    ElMessage.success('发布成功！');
    flushSceneList();
  });
};

const handleCurrentPageChange = (_val: number) => {
  flushSceneList();
};

const handleSizeChange = (_val: number) => {
  flushSceneList();
};

onBeforeMount(() => {
  isLoading.value = true;
  isAdminFn();
  getAdminInfo();
  flushSceneList();
});
</script>

<template>
  <Page
    oncontextmenu="return false"
    onselectstart="return false"
    title=""
    auto-content-height
    class="flex h-full flex-col"
  >
    <template #title>
      <div class="head flex w-full items-center overflow-hidden px-3">
        <!-- 左侧创建按钮 -->
        <div class="flex flex-[1] justify-start">
          <ElButton
            type="primary"
            :icon="ElPlus"
            size="large"
            plain
            @click="handleCreateSceneConfirm"
            text
          >
            {{ $t('scenes.createScene') }}
          </ElButton>
        </div>

        <!-- 搜索框 -->
        <div class="flex w-full flex-[9] justify-center">
          <ElInput
            v-model="keyword"
            @keyup.enter="flushSceneList"
            size="large"
            :placeholder="$t('scenes.searchScene')"
            clearable
            @clear="flushSceneList"
          >
            <template #append>
              <ElButton :icon="ElSearch" @click="flushSceneList" />
            </template>
          </ElInput>
        </div>

        <!-- 右侧下拉菜单 -->
        <div class="flex flex-[1] items-center justify-end space-x-4">
          <ElDropdown @command="handleSortCommand" trigger="hover">
            <span
              class="ml-4 flex cursor-pointer items-center text-blue-500 outline-none"
            >
              <ElIcon size="20">
                <ElSort />
              </ElIcon>
              &nbsp;
              <div class="hidden whitespace-nowrap text-base lg:block">
                {{ activeSortedField?.label }}
              </div>
              <ElIcon class="el-icon--right">
                <ElArrowDown />
              </ElIcon>
            </span>
            <template #dropdown>
              <ElDropdownMenu>
                <ElDropdownItem command="updateTime" :icon="ElClock">
                  {{ $t('scenes.sortBy.updateTime') }}
                </ElDropdownItem>
                <ElDropdownItem command="createTime" :icon="ElCalendar">
                  {{ $t('scenes.sortBy.createTime') }}
                </ElDropdownItem>
                <ElDropdownItem command="name" :icon="ElDataAnalysis">
                  {{ $t('scenes.sortBy.name') }}
                </ElDropdownItem>
              </ElDropdownMenu>
            </template>
          </ElDropdown>
        </div>
        <!-- 切换查看方式 -->
        <div class="ml-2 flex flex-[1] items-center justify-end">
          <ElButton
            type="primary"
            plain
            @click="toggleDisplayType"
            class="flex items-center space-x-2"
          >
            <ElIcon size="22">
              <component :is="isGridMode ? ElList : ElGrid" />
            </ElIcon>
            <span>
              {{
                isGridMode
                  ? $t('scenes.displayType.list')
                  : $t('scenes.displayType.grid')
              }}显示
            </span>
          </ElButton>
        </div>
      </div>
    </template>

    <!-- 格网模式 -->
    <template v-if="activeSceneDisplayType?.value === 'grid'">
      <div class="flex h-full flex-col bg-white dark:bg-black">
        <!-- 内容区域（允许滚动） -->
        <div class="flex-1 overflow-auto p-4 text-center">
          <template v-if="isSceneEmpty">
            <ElEmpty
              :image-size="250"
              :description="$t('scenes.emptyState.noScenes')"
            />
          </template>
          <template v-else>
            <ElEmpty
              :image-size="250"
              v-if="isSearchEmpty"
              :description="$t('scenes.emptyState.noSearchResults')"
            />

            <!-- 有数据 -->
            <template v-else>
              <ElCol>
                <!-- 骨架屏加载 -->
                <div
                  v-if="isLoading"
                  class="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
                >
                  <template v-for="index in 8" :key="index">
                    <ElCard
                      class="h-full w-full overflow-hidden rounded-2xl p-2 shadow-lg transition-all"
                    >
                      <div
                        class="h-60 w-full animate-pulse bg-gray-200 dark:bg-gray-700"
                      ></div>
                      <div class="bg-white p-5 dark:bg-black">
                        <div
                          class="h-4 w-3/4 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                        ></div>
                        <div class="mt-3 space-y-2">
                          <div
                            class="h-3 w-5/6 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                          ></div>
                          <div
                            class="h-3 w-2/3 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                          ></div>
                          <div
                            class="h-3 w-3/4 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                          ></div>
                        </div>
                        <div class="mt-4 flex items-center border-t pt-4">
                          <div
                            class="h-8 w-8 animate-pulse rounded-full bg-gray-300 dark:bg-gray-600"
                          ></div>
                          <div
                            class="ml-3 h-4 w-20 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                          ></div>
                          <div class="ml-auto flex space-x-2">
                            <div
                              v-for="i in 5"
                              :key="i"
                              class="h-8 w-8 animate-pulse rounded-full bg-gray-300 dark:bg-gray-600"
                            ></div>
                          </div>
                        </div>
                      </div>
                    </ElCard>
                  </template>
                </div>

                <!-- 场景卡片展示 -->
                <div
                  v-else
                  class="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4"
                >
                  <template
                    v-for="(scene, index) in currentSceneList.data"
                    :key="index"
                  >
                    <ElCard
                      shadow="hover"
                      class="h-full w-full overflow-hidden rounded-2xl p-2 shadow-lg transition-all"
                      :body-style="{ padding: '0px' }"
                    >
                      <!-- 场景缩略图 -->
                      <div
                        class="relative h-60 w-full cursor-pointer overflow-hidden transition-all hover:brightness-75"
                        :title="$t('scenes.card.enterScene')"
                        @click="enterScene('created', scene.sceneType, scene)"
                      >
                        <img
                          v-if="scene.sceneImg"
                          class="h-full w-full object-cover transition-transform duration-300 hover:scale-105"
                          :src="scene.sceneImg"
                        />
                        <div
                          v-else
                          class="flex h-full w-full items-center justify-center"
                        >
                          <ElEmpty
                            :image-size="100"
                            :description="$t('scenes.card.noThumbnail')"
                          />
                        </div>
                        <span
                          class="absolute bottom-3 right-3 rounded-full px-3 py-1 text-xs font-medium text-white shadow-md"
                          :class="getTypeColor()"
                        >
                          {{ displaySceneType() }}
                        </span>
                      </div>

                      <!-- 场景详情 -->
                      <div class="bg-white p-5 dark:bg-black">
                        <div
                          class="text-center text-base font-bold text-blue-500"
                        >
                          {{ scene.sceneName }}
                        </div>
                        <div
                          class="mt-3 space-y-2 whitespace-nowrap text-left text-sm"
                        >
                          <p class="flex items-center">
                            <ElIcon size="16" class="mr-1">
                              <ElCalendar />
                            </ElIcon>
                            {{ $t('scenes.card.createdTime') }}：
                            <time class="ml-1">{{ scene.createdTime }} </time>
                          </p>
                          <p class="flex items-center">
                            <ElIcon size="16" class="mr-1">
                              <ElRefresh />
                            </ElIcon>
                            {{ $t('scenes.card.lastUpdatedTime') }}：<time
                              class="ml-1"
                              >{{ scene.lastUpdatedTime }}
                            </time>
                          </p>
                          <p class="flex items-center">
                            <ElIcon size="16" class="mr-1">
                              <ElEdit />
                            </ElIcon>
                            {{ $t('scenes.card.editCount') }}：<time
                              class="ml-1"
                              >{{ scene.editCount }}
                            </time>
                          </p>
                        </div>

                        <!-- 操作区域 -->
                        <div class="mt-4 flex items-center border-t pt-4">
                          <ElAvatar
                            :size="32"
                            class="cursor-pointer shadow-lg hover:scale-105"
                          >
                            {{ userName?.[0] || 'U' }}
                          </ElAvatar>

                          <span
                            class="cursor-pointer pl-3 text-xs font-medium text-blue-500 hover:underline"
                            >{{ userName }}
                          </span>
                          <div class="ml-auto flex space-x-2">
                            <ElButton
                              type="primary"
                              size="small"
                              :icon="ElEdit"
                              :title="$t('scenes.actions.edit')"
                              circle
                              @click="enterScene('created', scene)"
                            />
                            <ElButton
                              type="warning"
                              size="small"
                              :icon="ElStar"
                              :title="$t('scenes.actions.favorite')"
                              circle
                            />
                            <ElButton
                              type="success"
                              size="small"
                              :icon="ElShare"
                              :title="$t('scenes.actions.share')"
                              circle
                            />
                            <ElButton
                              type="danger"
                              size="small"
                              :icon="ElDelete"
                              :title="$t('scenes.actions.delete')"
                              circle
                              @click="deleteScene(scene.sceneId)"
                            />
                            <ElButton
                              v-if="isAdmin"
                              type="primary"
                              plain
                              size="small"
                              :icon="ElUploadFilled"
                              :title="$t('scenes.actions.publish')"
                              circle
                              @click="publishScene(scene.sceneId)"
                            />
                          </div>
                        </div>
                      </div>
                    </ElCard>
                  </template>
                </div>

                <!-- 分页器 -->
              </ElCol>
            </template>
          </template>
        </div>
        <div v-if="!isSearchEmpty || !isSceneEmpty">
          <ElConfigProvider>
            <div class="flex w-full items-center justify-center py-3">
              <ElPagination
                @current-change="handleCurrentPageChange"
                @size-change="handleSizeChange"
                v-model:current-page="currentPage"
                v-model:page-size="pageSize"
                :page-sizes="[8, 16, 24]"
                layout="sizes, prev, pager, next, total"
                :total="totalDataCount"
                background
              />
            </div>
          </ElConfigProvider>
        </div>
      </div>
    </template>

    <!-- 列表模式 -->
    <template v-else>
      <div class="flex h-full flex-col bg-white dark:bg-black">
        <!-- 内容区域：自动撑高，滚动 -->
        <div class="flex-1 overflow-auto px-2 py-4">
          <!-- 骨架屏 -->
          <div v-if="isLoading" class="grid grid-cols-1 gap-1 lg:grid-cols-2">
            <template v-for="index in 8" :key="index">
              <div class="w-full p-2">
                <ElCard
                  shadow="hover"
                  class="relative p-2 shadow-lg"
                  :body-style="{ padding: '0px' }"
                >
                  <div class="flex h-40 w-full flex-row">
                    <div class="w-1/3">
                      <div
                        class="h-40 w-full animate-pulse bg-gray-200 dark:bg-gray-700"
                      ></div>
                    </div>
                    <div
                      class="ml-5 mt-2 flex flex-1 flex-col items-start justify-between"
                    >
                      <div
                        class="h-4 w-3/4 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                      ></div>
                      <div
                        class="h-3 w-5/6 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                      ></div>
                      <div
                        class="h-3 w-2/3 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                      ></div>
                      <div
                        class="h-3 w-3/4 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                      ></div>
                      <div
                        class="h-3 w-1/2 animate-pulse rounded bg-gray-300 dark:bg-gray-600"
                      ></div>
                    </div>
                    <div class="flex items-end pb-2 pr-2">
                      <div
                        class="h-8 w-8 animate-pulse rounded-full bg-gray-300 dark:bg-gray-600"
                      ></div>
                      <div
                        class="h-8 w-8 animate-pulse rounded-full bg-gray-300 dark:bg-gray-600"
                      ></div>
                      <div
                        class="h-8 w-8 animate-pulse rounded-full bg-gray-300 dark:bg-gray-600"
                      ></div>
                    </div>
                  </div>
                </ElCard>
              </div>
            </template>
          </div>

          <!-- 空内容 -->
          <template v-else-if="isSceneEmpty || isSearchEmpty">
            <div class="flex h-full items-center justify-center">
              <ElEmpty
                :image-size="250"
                :description="isSceneEmpty ? '暂无场景' : '暂无相关场景'"
              />
            </div>
          </template>

          <!-- 实际内容 -->
          <template v-else>
            <div class="grid grid-cols-1 gap-1 lg:grid-cols-2">
              <div
                v-for="(scene, index) in currentSceneList.data"
                :key="index"
                class="w-full p-2"
              >
                <ElCard
                  shadow="hover"
                  class="relative p-2 shadow-lg"
                  :body-style="{ padding: '0px' }"
                >
                  <span
                    class="absolute right-2 top-2 rounded-full px-3 py-1 text-xs font-medium text-white shadow-md"
                    :class="getTypeColor()"
                  >
                    {{ displaySceneType() }}
                  </span>

                  <div class="flex h-40 w-full flex-row">
                    <div class="w-1/3">
                      <img
                        :title="$t('scenes.card.enterScene')"
                        class="h-40 w-full cursor-pointer object-cover"
                        @click="enterScene('created', scene)"
                        v-if="scene.sceneImg"
                        :src="scene.sceneImg"
                      />
                      <ElEmpty
                        :title="$t('scenes.card.enterScene')"
                        @click="enterScene('created', scene)"
                        class="h-40 w-full cursor-pointer"
                        v-else
                        :image-size="100"
                        :description="$t('scenes.card.noThumbnail')"
                      />
                    </div>
                    <div
                      class="ml-5 mt-2 flex flex-1 flex-col items-start justify-between"
                    >
                      <span class="text-base font-bold text-blue-500">{{
                        scene.sceneName
                      }}</span>
                      <div class="text-sm">
                        {{ $t('scenes.card.createdTime') }}：
                        <time class="text-xs italic">{{
                          scene.createdTime
                        }}</time>
                      </div>
                      <div class="text-sm">
                        {{ $t('scenes.card.lastUpdatedTime') }}：
                        <time class="text-xs italic">{{
                          scene.lastUpdatedTime
                        }}</time>
                      </div>
                      <div class="text-sm">
                        {{ $t('scenes.card.editCount') }}：
                        <time class="text-xs italic">{{
                          scene.editCount
                        }}</time>
                      </div>
                      <div class="text-sm">
                        {{ $t('scenes.card.owner') }}：
                        <time class="text-xs italic">{{ userName }}</time>
                      </div>
                    </div>
                    <div class="flex items-end pb-2 pr-2">
                      <ElTooltip
                        :content="$t('scenes.actions.edit')"
                        placement="top"
                      >
                        <ElButton
                          circle
                          size="small"
                          type="primary"
                          :icon="ElEdit"
                          @click="enterScene('created', scene)"
                        />
                      </ElTooltip>
                      <ElTooltip
                        :content="$t('scenes.actions.favorite')"
                        placement="top"
                      >
                        <ElButton
                          type="warning"
                          size="small"
                          :icon="ElStar"
                          :title="$t('scenes.actions.favorite')"
                          circle
                        />
                      </ElTooltip>
                      <ElTooltip
                        :content="$t('scenes.actions.share')"
                        placement="top"
                      >
                        <ElButton
                          type="success"
                          size="small"
                          :icon="ElShare"
                          :title="$t('scenes.actions.share')"
                          circle
                        />
                      </ElTooltip>
                      <ElTooltip
                        :content="$t('scenes.actions.delete')"
                        placement="top"
                      >
                        <ElButton
                          circle
                          size="small"
                          type="danger"
                          :icon="ElDelete"
                          @click="deleteScene(scene.sceneId)"
                        />
                      </ElTooltip>
                      <ElTooltip
                        :content="$t('scenes.actions.publish')"
                        placement="top"
                        v-if="isAdmin"
                      >
                        <ElPopconfirm
                          title="确认要发布这个场景吗？"
                          @confirm="() => publishScene(scene.sceneId)"
                          width="300"
                          class="pl-2"
                        >
                          <template #reference>
                            <ElButton
                              circle
                              plain
                              size="small"
                              :icon="ElUploadFilled"
                            />
                          </template>
                        </ElPopconfirm>
                      </ElTooltip>
                    </div>
                  </div>
                </ElCard>
              </div>
            </div>
          </template>
        </div>

        <!-- 分页条固定在底部 -->
        <div v-if="!isSearchEmpty || !isSceneEmpty">
          <ElConfigProvider>
            <div class="flex w-full items-center justify-center py-3">
              <ElPagination
                @current-change="handleCurrentPageChange"
                @size-change="handleSizeChange"
                v-model:current-page="currentPage"
                v-model:page-size="pageSize"
                :page-sizes="[8, 16, 24]"
                layout="sizes, prev, pager, next, total"
                :total="totalDataCount"
                background
              />
            </div>
          </ElConfigProvider>
        </div>
      </div>
    </template>
  </Page>
</template>
